/*
 * Copyright 2008-2023 dexian.vip. All rights reserved.
 * Support: http://www.dexian.vip
 * License: http://www.dexian.vip/license
 */

package vip.dexian.common.utils;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * web 相关工具
 *
 * @author 挺好的 2023年05月31日 18:13
 */
@Slf4j
public final class WebUtils {

    /**
     * localhost
     */
    private static final String LOCALHOST_IP4 = "127.0.0.1";

    /**
     * localhost
     */
    private static final String LOCALHOST_IP6 = "0:0:0:0:0:0:0:1";

    /**
     * 未知
     */
    private static final String UN_KNOW = "UN_KNOWN";

    /**
     * ajax请求头名称
     */
    private static final String AJAX_REQUEST_HEADER_NAME = "X-Requested-With";

    /**
     * ajax请求头值
     */
    private static final String AJAX_REQUEST_HEADER_VALUE = "XMLHttpRequest";

    private WebUtils () {
    }

    /**
     * 是否是ajax请求
     *
     * @param request
     *         {@link HttpServletRequest}
     *
     * @return 是否是使用ajax发送请求
     */
    public static boolean isAjaxRequest (HttpServletRequest request) {
        String requestType = request.getHeader(AJAX_REQUEST_HEADER_NAME);
        return StringUtils.equalsIgnoreCase(requestType, AJAX_REQUEST_HEADER_VALUE);
    }

    /**
     * 响应json消息
     *
     * @param response
     *         {@link HttpServletResponse}
     * @param message
     *         {@link vip.dexian.common.Message}
     * @param contentType
     *         响应头。如果不传递，默认为 application/json;charset=utf-8
     */
    public static void responseMessage (HttpServletResponse response, Object message, String contentType) {

        try (PrintWriter out = response.getWriter()) {
            response.setContentType(StringUtils.isEmpty(contentType) ? "application/json;charset=utf-8" : contentType);
            out.write(JsonUtils.toJson(message));
            out.flush();
        } catch (IOException e) {
            log.error("写入响应消息失败！", e);
        }
    }

    /**
     * 响应json消息
     *
     * @param response
     *         {@link HttpServletResponse}
     * @param message
     *         {@link vip.dexian.common.Message}
     */
    public static void responseMessage (HttpServletResponse response, Object message) {
        responseMessage(response, message, "application/json;charset=utf-8");
    }

    /**
     * 获取客户端ip
     *
     * @param request
     *         {@link HttpServletRequest}
     *
     * @return IP 地址。
     */
    public static String getIPAddr (HttpServletRequest request) {
        if (request == null) {
            return null;
        }
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isEmpty(ip) || UN_KNOW.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if (StringUtils.isEmpty(ip) || UN_KNOW.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if (StringUtils.isEmpty(ip) || UN_KNOW.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }

        if (StringUtils.isEmpty(ip) || UN_KNOW.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }

        if (StringUtils.isEmpty(ip) || UN_KNOW.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        if (LOCALHOST_IP4.equals(ip) || LOCALHOST_IP6.equals(ip)) {
            return WebUtils.getLocalhost();
        }

        return ip;
    }

    /**
     * 获取本地ip
     *
     * @return 本地ip地址，如果无法获取，返回空{@link org.apache.commons.lang3.StringUtils#EMPTY}。
     */
    public static String getLocalhost () {
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            return StringUtils.EMPTY;
        }
    }
}
